package com.indigon.turing.view
{
	import com.indigon.turing.data.ArenaData;
	import com.indigon.turing.model.Model;
	import com.indigon.turing.model.hex.Hex;
	import com.indigon.turing.model.hex.HexCoords;
	import com.indigon.turing.model.hex.HexUtils;
	
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.geom.Point;

	public class Renderer extends Sprite
	{
		public static const CANVAS_SIZE : uint = 500;
		public static const HALF_CANVAS_SIZE : uint = CANVAS_SIZE / 2;
		
		public static const HEX_SIZE : Number = 3;
		
		public static const HALF_HEX_SIZE : Number = HEX_SIZE;
		public static const HALF_HEX_HEIGHT : Number = HEX_SIZE * Math.sqrt(3);
		
		public static const BLOCK_COLOR  : uint  = 0xaaaaaa;
		public static const PLAYER_COLOR : Array = [ 0x000000, 0xff0000, 0x00ff00, 0xffff00];
		
		private var _model : Model;
		
		private var _effectsLayer : Shape;
		
		public function Renderer(model:Model)
		{
			this._model = model;
			_effectsLayer = new Shape();
			addChild(_effectsLayer);
		}
		
		public function reset():void
		{
			graphics.clear();
			_effectsLayer.graphics.clear();
		}
		
		public function configure(data:ArenaData):void
		{
			// fill bg.
			graphics.beginFill(PLAYER_COLOR[Model.EMPTY_PLAYER], 1);
			graphics.drawRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
			graphics.endFill();
			
			var p : Point;
			
			// draw blocks.
			for each (var blockCoords : HexCoords in data.blocks)
			{
				p = getDrawingCoords(blockCoords.orbit, blockCoords.slot);
				drawHex(p.x, p.y, BLOCK_COLOR, 1, this);
			}
			
			// draw players start position.
			for (var i : uint = 0; i < data.startPos.length; i++)
			{
				p = getDrawingCoords(data.startPos[i].orbit, data.startPos[i].slot);
				drawHex(p.x, p.y, PLAYER_COLOR[i + 1], 1, this);
			}
		}
		
		public function update():void
		{
			var p : Point;
			
			_effectsLayer.graphics.clear();
			
			// draw updated hexes.
			for each (var hex : Hex in _model.updatedHexes)
			{
				p = getDrawingCoords(hex.orbit, hex.slot);
				drawHex(p.x, p.y, PLAYER_COLOR[Model.EMPTY_PLAYER], 1, this);
				drawHex(p.x, p.y, PLAYER_COLOR[hex.player], hex.value, this);
			}
		}
		
		private function getDrawingCoords(orbit:uint, slot:uint):Point
		{
			var p : Point = new Point(HALF_CANVAS_SIZE, HALF_CANVAS_SIZE);
			
			if (orbit > 0)
			{
				var maxSlots : uint   = HexUtils.slotsPerOrbit(orbit);
				var angle    : Number = ((4 * (slot / maxSlots) - 1) * Math.PI) * 0.5;  
				var radius   : Number = HALF_HEX_HEIGHT * orbit * 2;
				var polarP   : Point  = Point.polar(radius, angle);
				p = p.add(polarP);
			}
			return p;
		}
		
		private function drawHex(x:Number, y:Number, color:uint, alpha:Number, on:Object):void
		{
			on.graphics.beginFill(color, alpha);
			
			on.graphics.moveTo(x + -HALF_HEX_SIZE, y - HALF_HEX_HEIGHT);
			on.graphics.lineTo(x + HALF_HEX_SIZE, y - HALF_HEX_HEIGHT);
			on.graphics.lineTo(x + HALF_HEX_SIZE + HALF_HEX_SIZE, y);
			on.graphics.lineTo(x + HALF_HEX_SIZE, y + HALF_HEX_HEIGHT);
			on.graphics.lineTo(x + -HALF_HEX_SIZE, y + HALF_HEX_HEIGHT);
			on.graphics.lineTo(x + -HALF_HEX_SIZE - HALF_HEX_SIZE, y);
			on.graphics.lineTo(x + -HALF_HEX_SIZE, y - HALF_HEX_HEIGHT);
		}
	}
}